/**
 * Created by msi on 2017/6/4.
 */
import java.util.Stack;
import java.util.StringTokenizer;

/**
 * Demonstrates the use of a stack to evaluate postfix expression
 */
public class PostfixEvaluator2 {

    /**
     * constants for four calculative symbols
     */
    private final char ADD = '+';
    private final char SUBTRACT = '-';
    private final char MULTIPLY = '*';
    private final char DIVIDE = '/';

    private Stack<Integer> stack;

    /**
     * Initialize with an empty stack<Integer>
     */
    public PostfixEvaluator2(){
        stack = new Stack<Integer>();
    }

    /**
     * Determines if the specified char is an operator
     */
    private boolean isOperator(String str) {

        return (str.equals("+") || str.equals("-") || str.equals("*") || str
                .equals("/"));
    }

    /**
     * Calculate
     */
    private int calculateSingleOp(char operator, int num1, int num2) {

        int result = 0;
        switch (operator)
        {
            case ADD:
                result = num1 + num2;
                break;
            case SUBTRACT:
                result = num1 - num2;
                break;
            case MULTIPLY:
                result = num1 * num2;
                break;
            case DIVIDE:
                result = num1 / num2;
                break;
        }

        return result;
    }

    /**
     * Evaluates the specified postfix expression
     * if an operand is encountered, push it onto the stack.
     * if an operator is encountered, pop two operand for operator to evaluate
     * and push the calculated result onto the stack
     */
    public int evaluate (String str){

        int num1, num2, result = 0;
        // Temporary vase for every single char
        String token = "";
        StringTokenizer tokenizer = new StringTokenizer(str);

        while (tokenizer.hasMoreTokens()){
            // Tokenizer every single char from String
            token = tokenizer.nextToken();

            if (isOperator(token)){
                // Transfer Integer object into int
                num2 = (stack.pop()).intValue();
                num1 = (stack.pop()).intValue();
                result = calculateSingleOp(token.charAt(0), num1, num2);
                // Push the calculated result onto the stack
                stack.push(new Integer(result));
            }
            else
            {
                stack.push(new Integer(Integer.parseInt(token)));
            }
        }
        return result;
    }

}